﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Xml.Serialization
Imports System.Web

Namespace roncliProductions.LibWowArmory

    ''' <summary>
    ''' A class that retrieves a character's reputation from the Armory
    ''' </summary>
    ''' <remarks></remarks>
    Public Class CharacterReputation
        Inherits WowArmoryData

#Region "Declarations"

        Private crPage As New CharacterReputationSchema.page
        Private strRealm As String
        Private strName As String
        Private rReputation As New List(Of Reputation)

#End Region

        ''' <summary>
        ''' The realm the character is on
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Realm() As String
            Get
                Return strRealm
            End Get
            Set(ByVal value As String)
                strRealm = value
            End Set
        End Property

        ''' <summary>
        ''' The name of the character
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Name() As String
            Get
                Return strName
            End Get
            Set(ByVal value As String)
                strName = value
            End Set
        End Property

        ''' <summary>
        ''' The URL that will be used to retrieve the character's reputation from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property URL() As String
            Get
                Return String.Format("http://www.wowarmory.com/character-reputation.xml?r={0}&n={1}", strRealm, strName)
            End Get
        End Property

        ''' <summary>
        ''' Indicates to the inherited class that this request does not require login
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property RequiresLogin() As Boolean
            Get
                Return False
            End Get
        End Property

        ''' <summary>
        ''' The character's list of reputations
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Reputation() As List(Of Reputation)
            Get
                Return rReputation
            End Get
            Set(ByVal value As List(Of Reputation))
                rReputation = value
            End Set
        End Property

        ''' <summary>
        ''' The date this character was last modified on the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property LastModified() As Date
            Get
                Return CDate(crPage.characterInfo.First().character.First().lastModified)
            End Get
        End Property

        ''' <summary>
        ''' A constructor to load a character's reputation by realm and character name
        ''' </summary>
        ''' <param name="strRealm"></param>
        ''' <param name="strName"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal strRealm As String, ByVal strName As String)
            Me.strRealm = strRealm
            Me.strName = strName
            Load()
        End Sub

        ''' <summary>
        ''' Loads the character's reputation from the armory
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            Dim strKey As String = String.Format("LibWowArmory.CharacterReputation.{0}.{1}", strRealm, strName)
            If Cache.Cache(strKey) Is Nothing Then
                MyBase.Retrieve()

                Dim xsSerializer As New XmlSerializer(crPage.GetType())

                Dim srXML As New StringReader(MyBase.strData)

                crPage = CType(xsSerializer.Deserialize(srXML), CharacterReputationSchema.page)

                Cache.Cache.Insert(strKey, crPage, Nothing, Date.UtcNow.AddDays(1), Nothing, Caching.CacheItemPriority.Normal, Nothing)
            Else
                crPage = CType(Cache.Cache(strKey), CharacterReputationSchema.page)
            End If

            If crPage Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve reputation for does not exist.")
            End If
            If crPage.characterInfo Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve reputation for does not exist.")
            End If
            If crPage.characterInfo.First().character Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve reputation for does not exist.")
            End If
            If crPage.characterInfo.First().reputationTab Is Nothing Then
                Throw New ArgumentException("The character you are trying to retrieve reputation for does not exist.")
            End If

            For Each fFaction As CharacterReputationSchema.faction In crPage.characterInfo.First().reputationTab.First().faction
                AddFaction(rReputation, fFaction)
            Next
        End Sub

        Private Sub AddFaction(ByRef rReputations As List(Of Reputation), ByVal fFaction As CharacterReputationSchema.faction)
            Dim rNewReputation As New Reputation(fFaction.id, fFaction.name, fFaction.reputation)
            For Each fSubFaction As CharacterReputationSchema.faction In fFaction.faction
                AddFaction(rNewReputation.Reputations, fSubFaction)
            Next
            rReputations.Add(rNewReputation)
        End Sub

    End Class

End Namespace